﻿using System;
using System.IO;
using isvn.Helper;
using isvn.Base;

namespace isvn.Commands
{
    internal class Empty : CommandBase
    {
        #region -= Help =-

        private const string HelpText =
@"Description:
    Remove all files of specified directory except subversion ones.

Usage:
    isvn empty [path] [/s]

Options:
    /s      apply the operation recursively to the directory and its children folders.
";

        public override void Help()
        {
            Output.WriteHelp(HelpText);
        } 

        #endregion

        public override string CmdName
        {
            get { return "empty"; }
        }

        #region -= Execute =-

        private static bool IsSVNFolder(string folderName)
        {
            try
            {
                return folderName.EndsWith(".svn", StringComparison.InvariantCultureIgnoreCase)
                    || folderName.EndsWith("_svn", StringComparison.InvariantCultureIgnoreCase);
            }
            catch (Exception ex)
            {
                Output.WriteError("Error: " + ex.Message + Environment.NewLine);
            }

            return false;
        }

        private static void EmptyFolder(DirectoryInfo di, bool isRecursive)
        {
            if (null == di)
                return;

            if (!di.Exists)
            {
                Output.WriteError("The following path was not found:\r\n\t" + di.FullName + Environment.NewLine);
                return;
            }

            if (IsSVNFolder(di.FullName))
                return;

            FileInfo[] files;
            try
            {
                files = di.GetFiles();
            }
            catch
            {
                Output.WriteError("Could not get files from folder:\r\n\t" + di.FullName + Environment.NewLine);
                return;
            }

            foreach (FileInfo file in files)
            {
                try
                {
                    file.Delete();
                }
                catch (Exception ex)
                {
                    var msg = string.Format("Could not remove below file:\r\n\t{0}\r\nError message: {1}\r\n", file.FullName, ex.Message);
                    Output.Write(msg);
                }
            }

            if (!isRecursive)
                return;

            DirectoryInfo[] childDirs;
            try
            {
                childDirs = di.GetDirectories();
            }
            catch
            {
                Output.WriteError("Could not get subdirectories from folder:\r\n\t" + di.FullName + Environment.NewLine);
                return;
            }

            foreach (DirectoryInfo child in di.GetDirectories())
                EmptyFolder(child, true);
        }

        private void ParseArgs(string[] args, out string path, out bool recursive)
        {
            path = null;
            recursive = false;
            if (!ValidateArgs(args))
                return;

            foreach (string s in args)
            {
                if (string.IsNullOrEmpty(s) || 0 == string.Compare(s, CmdName, true))
                    continue;
                else if (0 == string.Compare(s, "/s", true))
                    recursive = true;
                else if (!s.StartsWith("/"))
                    path = s;
            }
        }

        //isvn empty [path] /s
        public override void Execute(string[] args)
        {
            string path;
            bool isRecursive;
            ParseArgs(args, out path, out isRecursive);

            if (string.IsNullOrEmpty(path))
            {
                Output.WriteQuestion("Empty current folder? yes or no: ");
                ConsoleKeyInfo keyinfo = Console.ReadKey();
                if ('Y' == keyinfo.KeyChar || 'y' == keyinfo.KeyChar)
                {
                    Output.Write("\r\nYou can use \"isvn empty .\" to empty current folder for short.\r\n");
                    path = ".\\";
                }
                else
                {
                    Help();
                    return;
                }
            }

            if (!Directory.Exists(path))
            {
                Output.WriteError("The following path was not found:\r\n\t" + path + Environment.NewLine);
                return;
            }

            try
            {
                DirectoryInfo dir = new DirectoryInfo(path);
                EmptyFolder(dir, isRecursive);
                Output.WriteSuccess("Folder emptied:\r\n\t" + dir.FullName + Environment.NewLine);
            }
            catch (Exception ex)
            {
                var msg = string.Format("Could not empty the following directory:\r\n\t{0}\r\nError message: {1}\r\n", path, ex.Message);
                Output.WriteError(msg);
            }
        }

        #endregion
    }
}
